import {promises as fs} from 'fs';
import path from 'path';
import markdownIt from 'markdown-it';
import markdownItAnchor from 'markdown-it-anchor';

// 自定义 markdown-it 插件
import markdownImagePlugin from "./markdown-it/markdown-image-plugin.ts";
import markdownImageAttributesPlugin from "./markdown-it/markdown-image-attributes-plugin.ts";

export default function markdownHtmlPlugin(options: any = {}) {
    const {dir = 'blogs'} = options;
    let markdownMap = {};
    return {
        name: 'vite-plugin-markdown-html',
        async configResolved(config) {
            const fullDirPath = path.resolve(config.root, dir);
            await scanMarkdownFiles(fullDirPath);
        },
        resolveId(id) {
            if (id === '@markdown-map') {
                return id; // 确保返回虚拟模块 ID
            }
        },
        load(id) {
            if (id === '@markdown-map') {
                return `export default ${JSON.stringify(markdownMap)};`; // 返回包含 Markdown 文件信息的对象
            }
        },
    };

    /**
     * Modify img src attributes to absolute paths.
     * @param {string} content - The original Markdown content.
     * @param {string} baseDir - The base directory for relative paths.
     * @returns {string} - The modified Markdown content.
     */
    function modifyImgSrc(content, baseDir) {
        return content.replace(/<img\s+([^>]*?)src=["']([^"']+)["']/gi, (match, preAttrs, src) => {
            if (!src.startsWith('http') && !src.startsWith('/')) { // Only modify relative paths
                src = `${baseDir}/${src}`;
            }
            return `<img ${preAttrs}src="${src}"`;
        });
    }

    /**
     * Custom plugin to add ::marker for ordered lists
     */
    function listMarkerPlugin(md) {
        const defaultRenderListItemOpen = md.renderer.rules.list_item_open || function(tokens, idx, options, env, self) {
            return self.renderToken(tokens, idx, options);
        };

        md.renderer.rules.ordered_list_open = function(tokens, idx, options, env, self) {
            tokens[idx].attrPush(['class', 'custom-list']);
            return defaultRenderListItemOpen(tokens, idx, options, env, self);
        }

        md.renderer.rules.list_item_open = function(tokens, idx, options, env, self) {
            // tokens[idx].attrPush(['style', 'list-style-type:none;']);
            tokens[idx].attrPush(['class', 'custom-list-item']);
            return defaultRenderListItemOpen(tokens, idx, options, env, self);
        };
    }

    async function scanMarkdownFiles(dirPath) {
        const files = await fs.readdir(dirPath);

        for (const file of files) {
            const fullFilePath = path.join(dirPath, file);
            const stat = await fs.stat(fullFilePath);

            if (stat.isDirectory()) {
                await scanMarkdownFiles(fullFilePath); // 递归扫描子目录
            } else if (file.endsWith('.md')) {
                const relativeFilePath = path.relative(process.cwd(), fullFilePath);

                // Read the content and parse it with markdown-it to extract HTML and headings.
                let content = await fs.readFile(fullFilePath, 'utf-8');

                // Modify img src attributes before parsing

                console.log("relativeFilePath", relativeFilePath);
                // relativeFilePath = /myVite/blogs/01. react 的初步学习.md 去掉 /xxxx.md xxxx可能是任何字符串
                const fileName = path.basename(relativeFilePath);
                var basename = path.toNamespacedPath(relativeFilePath);
                // const rePath = relativeFilePath.replace(/\.md$/, '');
                // 去掉相对路径中的文件名部分，只保留目录部分
                const dirPath = path.dirname(relativeFilePath);
                console.log("fileName", fileName)
                console.log("basename", basename)
                console.log("dirPath", dirPath)
                content = modifyImgSrc(content, dirPath);


                // @ts-ignore
                const md = markdownIt({
                    html: true,
                    linkify: true,
                    typographer: true,
                    mdFilePath: dirPath,
                })
                    // 修改图片的路径
                    .use(markdownImagePlugin)
                    .use(listMarkerPlugin)
                    .use(markdownItAnchor, {
                        permalink: true,
                        permalinkBefore: true,
                        permalinkSymbol: '#',
                        slugify: s => s.trim().toLowerCase().replace(/[\s+~\/]/g, '-')
                    });

                let headings = [];

                // Collect headings during rendering
                md.core.ruler.push('collect_headings', state => {
                    state.tokens.forEach(token => {
                        if (token.type === 'heading_open') {
                            headings.push({
                                level: token.tag,
                                content: state.tokens[state.tokens.indexOf(token) + 1].content,
                                id: state.tokens[state.tokens.indexOf(token)].attrs[0][1]  // 获取ID属性值
                            });
                        }
                    });
                });

                // Render the content to HTML.
                const htmlContent = md.render(content);

                // Store the extracted data in the map.
                markdownMap[relativeFilePath] = {
                    htmlContent,
                    headings,
                };
            }
        }
    }
}
